package com.example.activity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.adapter.RvAdapter;
import com.example.interfacePackage.RvClickInterface;
import com.example.studyapplication.R;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import io.reactivex.rxjava3.annotations.NonNull;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableEmitter;
import io.reactivex.rxjava3.core.ObservableOnSubscribe;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.core.Observer;
import io.reactivex.rxjava3.disposables.Disposable;
import io.reactivex.rxjava3.functions.Consumer;
import io.reactivex.rxjava3.functions.Function;


/**
 * @Description:
 * @Author: 葛浩杰
 * @Version: 1.0 2021/3/25
 */
public class RxjavaActivity extends Activity {

    private RecyclerView recyclerView;
    private RvAdapter rvAdapter;
    private String TAG = "RxjavaActivity";
    private Observer<Integer> observer;
    private Disposable disposable;//取消interval

    public static void startActivity(Context context){
        context.startActivity(new Intent(context,RxjavaActivity.class));
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_rxjava);
        recyclerView = findViewById(R.id.rv_rxjava);

        observer = new Observer<Integer>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {
                Log.d(TAG, "开始采用subscribe连接");
            }

            @Override
            public void onNext(@NonNull Integer integer) {
                Log.d(TAG, "对Next事件"+ integer +"作出响应"  );
            }

            @Override
            public void onError(@NonNull Throwable e) {
                Log.d(TAG, "对Error事件作出响应");
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "对Complete事件作出响应");
            }
        };
        initData();
    }

    private List<String> getData() {
        List<String> rvData = new ArrayList<>();
        rvData.add("create");
        rvData.add("just");
        rvData.add("from");
        rvData.add("empty、error、never");
        rvData.add("timer");
        rvData.add("interval");
        rvData.add("range");
        rvData.add("onErrorReturnItem");
        rvData.add("onErrorResumeNext");
        rvData.add("onErrorReturn");
        return rvData;
    }

    private void initData() {
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        rvAdapter = new RvAdapter(this, getData());
        recyclerView.setAdapter(rvAdapter);
        rvAdapter.setOnItemClickListener(new RvClickInterface() {
            @Override
            public void OnItemClickListener(int position) {
                switch (position){
                    case 0:
                        createOperator();
                        break;
                    case 1:
                        justOperator();
                        break;
                    case 2:
                        fromOperator();
                        break;
                    case 3:
                        emptyOperator();
                        break;
                    case 4:
                        timerOperator();
                        break;
                    case 5:
                        intervalOperator();
                        break;
                    case 6:
                        rangeOperator();
                        break;
                    case 7:
                        onErrorReturnItem();
                        break;
                    case 8:
                        onErrorResumeNext();
                        break;
                    case 9:
                        onErrorReturn();
                        break;
                }
            }
        });
    }

    private void onErrorReturnItem() {
        Observable.just(1,2,3,4,5,6)
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Throwable {
                        return Observable.just(integer);
                    }
                })
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Throwable {
                        if(integer == 2){
                            return Observable.just(integer/0);
                        } else {
                            return Observable.just(integer+1);
                        }
                    }
                })
                .onErrorReturnItem(888)
                .map(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Throwable {
                        return integer-1;
                    }
                })
                .subscribe(observer);
    }

    private void onErrorResumeNext() {
        Observable.just(1,2,3,4,5,6)
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Throwable {
                        return Observable.just(integer);
                    }
                })
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Throwable {
                        if(integer == 2){
                            return Observable.just(integer/0);
                        } else {
                            return Observable.just(integer+1);
                        }
                    }
                })
                .onErrorResumeNext(new Function<Throwable, ObservableSource<? extends Integer>>() {
                    @Override
                    public ObservableSource<? extends Integer> apply(Throwable throwable) throws Throwable {
                        return Observable.just(999);
                    }
                })
                .map(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Throwable {
                        return integer-1;
                    }
                })
                .subscribe(observer);
    }

    private void onErrorReturn() {
        Observable.just(1,2,3,4,5,6)
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Throwable {
                        return Observable.just(integer);
                    }
                })
                .flatMap(new Function<Integer, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(Integer integer) throws Throwable {
                        if(integer == 2){
                            return Observable.just(integer/0);
                        } else {
                            return Observable.just(integer+1);
                        }
                    }
                })
                .onErrorReturn(new Function<Throwable, Integer>() {
                    @Override
                    public Integer apply(Throwable throwable) throws Throwable {
                        return 1000;
                    }
                })
                .map(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Throwable {
                        return integer-1;
                    }
                })
                .subscribe(observer);
    }

    /**
     * range
     */
    private void rangeOperator() {
        Observable.range(3,10).subscribe(observer);
    }

    /**
     * interval
     */
    private void intervalOperator() {
        Observable.interval(1, TimeUnit.SECONDS)
                .subscribe(new Observer<Long>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        disposable = d;
                    }

                    @Override
                    public void onNext(@NonNull Long aLong) {
                        Log.d(TAG, aLong + "");
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {

                    }

                    @Override
                    public void onComplete() {

                    }
                });
    }

    /**
     * timer
     */
    private void timerOperator() {
        Observable.timer(1000, TimeUnit.MILLISECONDS).subscribe(new Observer<Long>() {
            @Override
            public void onSubscribe(@NonNull Disposable d) {

            }

            @Override
            public void onNext(@NonNull Long aLong) {
                Log.d(TAG, aLong+"");//0
            }

            @Override
            public void onError(@NonNull Throwable e) {

            }

            @Override
            public void onComplete() {

            }
        });
    }

    /**
     * empty\error\never
     */
    private void emptyOperator() {
        Observable.<Integer>empty().subscribe(observer);
//        Observable.<Integer>error(new RuntimeException()).subscribe(observer);
//        Observable.<Integer>never().subscribe(observer);
    }

    /**
     * from
     */
    private void fromOperator() {
        Integer [] fromInteger = {1, 2, 3};
        Observable.fromArray(fromInteger).subscribe(observer);
    }

    /**
     * just
     */
    private void justOperator() {
        Observable.just(1 , 2, 3).subscribe(observer);
    }

    /**
     * create
     */
    private void createOperator() {
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(@NonNull ObservableEmitter<Integer> emitter) throws Throwable {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
                emitter.onComplete();
            }
        }).subscribe(observer);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(disposable != null){
            disposable.dispose();
        }
    }
}
